﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Zhongy
{
    public enum GameState
    {
        DISCONNECT = 0,
        CONNECT = 1,
        START = 2,
        PAUSE = 3,

        STOP = 4,
    }

    public class GameManager : MananerBase
    {
        public static GameManager Instance = null;

        private static GameState curState = GameState.DISCONNECT;

        public static GameState CurState
        {
            get { return curState; }
        }

        void Awake()
        {
            Instance = GetComponent<GameManager>();

            Bind(new int[5]
            {
                GameEvtCode.GameDisconnect,
                GameEvtCode.GameConnect,
                GameEvtCode.GameStop,
                GameEvtCode.GameStart,
                GameEvtCode.GamePuase,

            }, this);

            BindGameEvent.Game2ClientStart = Game2ClientStart;
            BindGameEvent.Game2ClientResume = Game2ClientResume;
            BindGameEvent.Game2ClientDisconnect = Game2ClientDisconnect;
            BindGameEvent.Game2ClientDebug = Game2ClientDebug;

            BindGameEvent.Game2ClientStop = Game2ClientStop;
        }

        void OnDestroy()
        {
        }

        public override void Execute(int evtCode, params object[] msg)
        {
            switch (evtCode)
            {
                case GameEvtCode.GameDisconnect:

                    if (curState != GameState.DISCONNECT)
                    {
                        Client2GameDisConnect();
                        curState = GameState.DISCONNECT;
                    }

                    break;

                case GameEvtCode.GameConnect:
                    Debug.LogError(curState);
                    if (curState != GameState.CONNECT
                        && curState != GameState.START
                        && curState != GameState.PAUSE)
                    {
                        Client2GameConnect();
                        curState = GameState.CONNECT;
                    }

                    break;

                case GameEvtCode.GameStop:
                {
                    if (curState != GameState.STOP)
                        Client2GameStop();
                    curState = GameState.STOP;
                }
                    break;

                case GameEvtCode.GameStart:
                    if (curState != GameState.START)
                    {
                        if (msg != null 
                            && msg[0] is string 
                            && ((string) msg[0]).IndexOf("resume")!=-1)
                        {
                            Client2GameResume();
                        }
                        else
                        {
                            Client2GameStart(msg);
                        }
                        curState = GameState.START;

                    }

                    break;

                case GameEvtCode.GamePuase:
                    if (curState != GameState.PAUSE)
                    {
                        Client2GamePause();
                        curState = GameState.PAUSE;
                    }

                    break;

                default:
                    Debug.LogError("信息归属不对");
                    break;
            }
        }

        /// <summary>
        /// 等待client连接
        /// 游戏初始化
        /// </summary>
        private void Client2GameDisConnect()
        {
#if DEBUG_MODEL
            Debug.LogError("等待client连接");
            Debug.LogError("游戏初始化");
#endif

            Loom.QueueOnMainThread(() =>
            {
                GameController.bClientQuit = true;

                if (BindGameEvent.GameDisConnect != null)
                    BindGameEvent.GameDisConnect();
            });

        }

        /// <summary>
        /// client接入游戏tcp
        /// 等待用户接入，开始游戏，或是退出游戏
        /// </summary>
        private void Client2GameConnect()
        {
            //重置游戏
#if DEBUG_MODEL
            Debug.LogError("client接入游戏tcp");
            Debug.LogError("等待用户接入，开始游戏，或是退出游戏");
#endif
            Loom.QueueOnMainThread(() =>
            {
                if (BindGameEvent.GameConnect != null)
                    BindGameEvent.GameConnect();
            });
        }

        private void Client2GameStop()
        {
#if DEBUG_MODEL
            Debug.LogError("client控制游戏结束");
#endif
            Loom.QueueOnMainThread(() =>
            {
                if (BindGameEvent.GameStop != null)
                    BindGameEvent.GameStop();
            });
        }

        /// <summary>
        /// client控制游戏开始
        /// client发送braindata数据
        /// </summary>
        private void Client2GameStart(params object[] msg)
        {
#if DEBUG_MODEL
            Debug.LogError("client控制游戏开始");
            Debug.LogError("client发送braindata数据");
#endif
            Loom.QueueOnMainThread(() =>
            {
                if (BindGameEvent.GameStart != null)
                    BindGameEvent.GameStart(msg);
            });
        }

        /// <summary>
        /// client控制游戏暂停
        /// </summary>
        private void Client2GamePause()
        {
            //todo
#if DEBUG_MODEL
            Debug.LogError("client控制游戏暂停");
#endif

            Loom.QueueOnMainThread(() =>
            {
                if (BindGameEvent.GamePause != null)
                    BindGameEvent.GamePause();
            });
        }

        /// <summary>
        /// client控制游戏继续
        /// </summary>
        private void Client2GameResume()
        {
#if DEBUG_MODEL
            Debug.LogError("client控制游戏继续");
#endif

            Loom.QueueOnMainThread(() =>
            {
                if (BindGameEvent.GameResume != null)
                    BindGameEvent.GameResume();
            });
        }

        /// <summary>
        /// 游戏向client申请开始游戏
        /// </summary>
        private void Game2ClientStart()
        {
#if DEBUG_MODEL
            Debug.Log("游戏向client申请开始游戏");
#endif

            SingleExecute.Instance.Execute(
                () =>
                {
                    SocketSendMsg sendMsg = new SocketSendMsg
                    {
                        MT = OpCode.TYPE_START_GAME_G,
                        mesgid = EncodeTool.GetTimestamp(DateTime.Now).ToString(),

                        Option = new RevOptionData
                        {
                            Time = GameConfig.CurGameTime <= 0 ? 30 : GameConfig.CurGameTime,
                            Difficulty = GameConfig.CurGameDifficulty
                        },
                        Player =  Cache.Player.GetPlayerIdLst(),
                        Restore = 0,
                    };

                    Dispatch(TransCode.Net, NetEvtCode.Clients2TcpMsgs, new object[] { sendMsg });

                    curState = GameState.START;
                    //改变广播状态值
                    Dispatch(TransCode.Net, GameEvtCode.GameStart);
                }
            );
        }

        /// <summary>
        /// 游戏向client申请继续游戏
        /// </summary>
        private void Game2ClientResume()
        {
#if DEBUG_MODEL
            Debug.Log("游戏向client申请继续游戏");
#endif
            SingleExecute.Instance.Execute(
                () =>
                {
                    SocketSendMsg sendMsg = new SocketSendMsg
                    {
                        MT = OpCode.TYPE_START_GAME_G,
                        mesgid = EncodeTool.GetTimestamp(DateTime.Now).ToString(),

                        Option = new RevOptionData
                        {
                            Time = GameConfig.CurGameTime<=0?30:GameConfig.CurGameTime,
                            Difficulty = GameConfig.CurGameDifficulty
                        },
                        Player = Cache.Player.GetPlayerIdLst(),
                        Restore = 1,
                    };

                    Dispatch(TransCode.Net, NetEvtCode.Clients2TcpMsgs, new object[] { sendMsg });

                    curState = GameState.START;
                    //改变广播状态值
                    Dispatch(TransCode.Net, GameEvtCode.GameStart);
                }
            );
        }

        /// <summary>
        /// 游戏向client申请结束游戏
        /// </summary>
        private void Game2ClientStop()
        {
#if  DEBUG_MODEL
            Debug.Log("游戏向client申请结束游戏");
#endif

            SingleExecute.Instance.Execute(
                () =>
                {
                    SocketSendMsg sendMsg = new SocketSendMsg
                    {
                        MT = OpCode.TYPE_STOP_GAME_G,
                        mesgid = EncodeTool.GetTimestamp(DateTime.Now).ToString(),
                    };

                    Dispatch(TransCode.Net, NetEvtCode.Clients2TcpMsgs, new object[] {sendMsg});

                    curState = GameState.STOP;
                    //改变广播状态值
                    Dispatch(TransCode.Net, GameEvtCode.GameStop);

                });
        }

        /// <summary>
        /// 游戏向client申请断开连接
        /// </summary>
        private void Game2ClientDisconnect()
        {
#if  DEBUG_MODEL
            Debug.Log("游戏向client申请断开连接");
#endif

            SingleExecute.Instance.Execute(() =>
            {
                Game2ClientStop();

                SocketSendMsg sendMsg = new SocketSendMsg
                {
                    MT =  OpCode.TYPE_GAME_DISCONNECT,
                    mesgid = EncodeTool.GetTimestamp(DateTime.Now).ToString(),
                };

                Dispatch(TransCode.Net, NetEvtCode.Clients2TcpMsgs, new object[] { sendMsg });


                curState = GameState.DISCONNECT;
                //改变广播状态值
                Dispatch(TransCode.Net, GameEvtCode.GameDisconnect);
            });
        }

        private void Game2ClientDebug(params object[] msgs)
        {
#if DEBUG_MODEL
            Debug.Log("游戏向client发送debug信息");
#endif
            if (msgs == null || msgs[0] == null)
            {
                Debug.LogError(string.Format("发送bug数据出错,{0}",msgs.ToString()));
                return;
            }

            SingleExecute.Instance.Execute(() =>
            {
                SocketSendMsg sendMsg = new SocketSendMsg
                {
                    MT = OpCode.TYPE_DEBUG_MSG_G,
                    Msg = msgs[0].ToString(),
                };
                Dispatch(TransCode.Net, NetEvtCode.Clients2TcpMsgs, new object[] { sendMsg });
            });

        }


        private void Dispatch(int transCode,int evtCode,params object[] message)
        {
            MsgCenter.Instance.Dispatch(transCode, evtCode, message);
        }

    }
}
